﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;

using BOSS.Dao.Security;
using BOSS.Domain.Security;
using BOSS.Framework;
using BOSS.Service.Caching;
using BOSS.Service.Security;

using Common.Logging;

using Spring.Transaction.Interceptor;

namespace BOSS.Service.Implements.Security
{
    public class SecurityService : ISecurityService
    {
        /// <summary>
        /// 日志器
        /// </summary>
        private static ILog logger = LogManager.GetLogger(typeof(SecurityService));

        /// <summary>
        /// 群组名称前缀
        /// </summary>
        private const string groupNamePrefix = "boss-";

        /// <summary>
        /// 群组名称前缀长度
        /// </summary>
        private const int groupNamePrefixLength = 5;

        #region DAOs

        /// <summary>
        /// 获取 / 设置 帐号 DAO
        /// </summary>
        public IAccountDao AccountDao { get; set; }

        /// <summary>
        /// 获取 / 设置 角色 DAO
        /// </summary>
        public IRoleDao RoleDao { get; set; }

        /// <summary>
        /// 获取 / 设置 群组 DAO
        /// </summary>
        //public IGroupDao GroupDao { get; set; }

        /// <summary>
        /// 获取 / 设置 用户基本信息 DAO
        /// </summary>
        //public IUserProfileDao UserProfileDao { get; set; }

        /// <summary>
        /// 获取 / 设置 权限 DAO
        /// </summary>
        public IPrivilegeDao PrivilegeDao { get; set; }

        /// <summary>
        /// 获取 / 设置 角色权限设置 DAO
        /// </summary>
        public IRolePrivilegeSettingDao RolePrivilegeSettingDao { get; set; }

        /// <summary>
        /// 获取 / 设置 群组权限设置 DAO
        /// </summary>
        //public IGroupPrivilegeSettingDao GroupPrivilegeSettingDao { get; set; }

        /// <summary>
        /// 获取 / 设置 帐号权限设置 DAO
        /// </summary>
        public IAccountPrivilegeSettingDao AccountPrivilegeSettingDao { get; set; }

        #endregion

        /// <summary>
        /// 运行时权限分配分类缓存
        /// Key = Account.Id
        /// Value = PrivilegeGroup
        /// </summary>
        private ICategoryCache<int, PrivilegeGroup> m_runtimePrivilegeCache;

        /// <summary>
        /// 设置 缓存服务
        /// </summary>
        public ICacheService CacheService
        {
            set
            {
                this.m_runtimePrivilegeCache = value.GetCategoryCache<int, PrivilegeGroup>("RuntimePrivileges");
            }
        }

        #region ISecurityService 成员

        ///// <summary>
        ///// 同步域信息
        ///// </summary>
        //[Transaction(ReadOnly = false)]
        //public void SyncDomain()
        //{
        //    using (SyncDomainContext context = new SyncDomainContext())
        //    {
        //        SyncDomainRoles(context);
        //        SyncDomainAccounts(context);
        //        SyncDomainGroups(context);
        //    }
        //    // 清除运行时权限缓存
        //    this.m_runtimePrivilegeCache.Clear();
        //}

        ///// <summary>
        ///// 同步域中的角色信息
        ///// </summary>
        //[Transaction(ReadOnly = false)]
        //public void SyncDomainRoles()
        //{
        //    using (SyncDomainContext context = new SyncDomainContext())
        //    {
        //        SyncDomainRoles(context);
        //    }
        //    // 清除运行时权限缓存
        //    this.m_runtimePrivilegeCache.Clear();
        //}

        ///// <summary>
        ///// 同步域中的群组信息
        ///// </summary>
        //[Transaction(ReadOnly = false)]
        //public void SyncDomainGroups()
        //{
        //    using (SyncDomainContext context = new SyncDomainContext())
        //    {
        //        SyncDomainGroups(context);
        //    }
        //    // 清除运行时权限缓存
        //    this.m_runtimePrivilegeCache.Clear();
        //}

        ///// <summary>
        ///// 同步域中的帐号信息
        ///// </summary>
        //[Transaction(ReadOnly = false)]
        //public void SyncDomainAccounts()
        //{
        //    using (SyncDomainContext context = new SyncDomainContext())
        //    {
        //        SyncDomainAccounts(context);
        //    }
        //    // 清除运行时权限缓存
        //    this.m_runtimePrivilegeCache.Clear();
        //}

        ///// <summary>
        ///// 同步域中的帐号信息
        ///// </summary>
        ///// <param name="accountInfo"></param>
        ///// <returns></returns>
        //[Transaction(ReadOnly = false)]
        //public Account SyncAccount(AccountInfo accountInfo)
        //{
        //    Check.Require(accountInfo != null);

        //    using (SyncDomainContext context = new SyncDomainContext())
        //    {
        //        Account account = this.AccountDao.FindByGuid(accountInfo.Guid);
        //        Staff staff = context.FindStaffByGuid(accountInfo.Guid);
        //        if (account == null)
        //        {
        //            if (staff == null)
        //            {
        //                // 使用 AccountInfo 新建帐号
        //                account = new Account()
        //                {
        //                    Guid = accountInfo.Guid,
        //                    Name = accountInfo.DisplayName,
        //                    EnglishName = accountInfo.EnglishName,
        //                    EmployeeId = accountInfo.EmployeeId,
        //                    Group = null,
        //                    GroupFromDomain = null,
        //                    Roles = new List<Role>(),
        //                };

        //                UserProfile profile = new UserProfile()
        //                {
        //                    Account = account,
        //                    IsDefaultEmail = true,
        //                };

        //                this.AccountDao.Save(account);
        //                this.UserProfileDao.Save(profile);

        //                if (logger.IsDebugEnabled)
        //                {
        //                    logger.Debug(string.Format("增加新帐号: {0} - {1}", account.Name, account.Guid));
        //                }
        //            }
        //            else
        //            {
        //                // 使用 Staff 新建帐号
        //                account = CreateAccount(context, staff);
        //            }
        //        }
        //        else
        //        {
        //            if (staff == null)
        //            {
        //                // 使用 AccountInfo 更新帐号
        //                account.Name = accountInfo.DisplayName;
        //                account.EnglishName = accountInfo.EnglishName;
        //                account.EmployeeId = accountInfo.EmployeeId;

        //                UserProfile profile = this.UserProfileDao.FindById(account.Id);
        //                if (profile == null)
        //                {
        //                    profile = new UserProfile()
        //                    {
        //                        Account = account,
        //                        Email = accountInfo.Email,
        //                        IsDefaultEmail = true,
        //                    };
        //                }

        //                this.AccountDao.SaveOrUpdate(account);
        //                this.UserProfileDao.SaveOrUpdate(profile);

        //                if (logger.IsDebugEnabled)
        //                {
        //                    logger.Debug(string.Format("更新帐号信息: {0} - {1}", account.Name, account.Guid));
        //                }
        //            }
        //            else
        //            {
        //                // 使用 Staff 更新帐号
        //                UpdateAccount(context, account, staff);
        //            }
        //        }

        //        // 清除运行时权限缓存
        //        this.m_runtimePrivilegeCache.Remove(account.Id);

        //        return account;
        //    }
        //}

        /// <summary>
        /// 获取所有权限
        /// </summary>
        /// <returns></returns>
        public IList<Privilege> SelectAllPrivileges()
        {
            return this.PrivilegeDao.SelectAll();
        }

        /// <summary>
        /// 查找指派给指定帐号的动态权限组（动态权限）
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public PrivilegeGroup GetDynamicPrivileges(Account account)
        {
            Check.Require(account != null);

            PrivilegeGroup cached = this.m_runtimePrivilegeCache.Get(account.Id);
            if (cached != null)
            {
                return cached;
            }

            IList<PrivilegeGroup> privilegeGroups = new List<PrivilegeGroup>();

            // 自身的权限
            {
                PrivilegeGroup privilegeGroup = this.AccountPrivilegeSettingDao.SelectByAccount(account);
                if (privilegeGroup != null)
                {
                    privilegeGroups.Add(privilegeGroup);
                }
            }

            // 所属角色的权限
            foreach (Role role in account.Roles)
            {
                PrivilegeGroup privilegeGroup = this.RolePrivilegeSettingDao.SelectByRole(role);
                if (privilegeGroup != null)
                {
                    privilegeGroups.Add(privilegeGroup);
                }
            }

            // 所在群组的权限
            //Group group = account.Group;
            //while (group != null)
            //{
            //    PrivilegeGroup privilegeGroup = this.GroupPrivilegeSettingDao.SelectByGroup(group);
            //    if (privilegeGroup != null)
            //    {
            //        privilegeGroups.Add(privilegeGroup);
            //    }
            //    group = group.ParentGroup;
            //}

            // 合并权限
            PrivilegeGroup result = PrivilegeGroup.MergeAll(privilegeGroups);

            // 修正已拒绝权限的子权限
            string deniedPrivilegeName = null;
            foreach (Privilege privilege in result.Privileges.OrderBy(p => p.Name))
            {
                if ((deniedPrivilegeName != null) && (privilege.IsChildOf(deniedPrivilegeName)))
                {
                    privilege.Permission = PermissionType.DENY;
                }
                else if (privilege.Permission == PermissionType.ALLOW)
                {
                    deniedPrivilegeName = null;
                }
                else
                {
                    deniedPrivilegeName = privilege.Name;
                }
            }

            // 缓存计算结果，并返回
            this.m_runtimePrivilegeCache.Add(account.Id, result);
            return result;
        }

        /// <summary>
        /// 查询满足给定权限的用户集合（使用动态权限查询，仅查询有效的用户）
        /// </summary>
        /// <param name="privilege"></param>
        /// <returns></returns>
        public IList<Account> SelectAccountsByPrivilege(Privilege privilege)
        {
            Check.Require(privilege != null);

            IList<Account> accounts = new List<Account>();

            foreach (Account account in this.AccountDao.SelectAllEnabled())
            {
                PrivilegeGroup privilegeGroup = this.GetDynamicPrivileges(account);
                foreach (Privilege toTest in privilegeGroup.Privileges)
                {
                    if (string.Equals(toTest.Name, privilege.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        if (toTest.Permission == privilege.Permission)
                        {
                            accounts.Add(account);
                        }
                    }
                }
            }

            return accounts;
        }

        /// <summary>
        /// 查询拥有给定权限的用户集合（使用动态权限查询，仅查询有效的用户）
        /// </summary>
        /// <param name="privilegeName"></param>
        /// <returns></returns>
        public IList<Account> SelectAccountsByPrivilege(string privilegeName)
        {
            Check.Require(!string.IsNullOrEmpty(privilegeName));

            return this.SelectAccountsByPrivilege(new Privilege(privilegeName, PermissionType.ALLOW));
        }

        /// <summary>
        /// 判断指定帐号是否有相应权限。
        /// 只有参考帐号、参考帐号的各级主管以及获得额外权限的帐号返回 true
        /// </summary>
        /// <param name="accountToBeChecked">待检查的帐号，一般为系统的当前帐号</param>
        /// <param name="referenceAccount">参考帐号，一般为待操作对象的拥有者。可以为 null</param>
        /// <param name="privilegeNames">额外的权限列表。若不指定则不进行权限识别</param>
        /// <returns></returns>
        public bool IsAuthorized(Account accountToBeChecked, Account referenceAccount, params string[] privilegeNames)
        {
            Check.Require(accountToBeChecked != null);

            if (accountToBeChecked.Equals(referenceAccount))
            {
                return true;
            }

            if (referenceAccount != null)
            {
                //Group group = referenceAccount.Group;
                //while (group != null)
                //{
                //    if (group.Manager != null && accountToBeChecked.Equals(group.Manager))
                //    {
                //        return true;
                //    }
                //    group = group.ParentGroup;
                //}
            }

            foreach (string privilegeName in privilegeNames)
            {
                IList<Account> accounts = this.SelectAccountsByPrivilege(privilegeName);
                if (accounts.Contains(accountToBeChecked))
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 刷新运行时权限缓存
        /// </summary>
        public void FlushRuntimePrivileges()
        {
            this.m_runtimePrivilegeCache.Clear();
        }

        /// <summary>
        /// 刷新指定用户的运行时权限缓存
        /// </summary>
        /// <param name="accountId"></param>
        public void FlushRuntimePrivileges(int accountId)
        {
            this.m_runtimePrivilegeCache.Remove(accountId);
        }

        /// <summary>
        /// 尝试用指定的登录名、密码登录系统
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="password"></param>
        /// <param name="domain"></param>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        public LoginInfo TryLogin(string loginName, string password, string ipAddress)
        {
            Account account = this.AccountDao.FindByLoginName(loginName);
            if (account == null || account.Disabled)
            {
                return null;
            }

            string hash = null;
            if (!string.IsNullOrEmpty(password))
            {
                hash = PasswordCryptor.Default.Encrypt(password);
            }

            if ( !(string.IsNullOrEmpty(account.Password) && string.IsNullOrEmpty(hash)) && account.Password != hash)
            {
                account = null;
            }

            if (account != null)
            {
                return new LoginInfo(Guid.NewGuid(), account, ipAddress);
            }
            return null;
        }

        /// <summary>
        /// 尝试远端登录
        /// </summary>
        /// <param name="token"></param>
        /// <param name="ipAddress"></param>
        /// <returns></returns>
        //public LoginInfo TryRemoteLogin(string token, string ipAddress)
        //{
        //    var loginInfo = this.AuthorizationService.GetLoginInfo("EPortal", token, ipAddress);
        //    if (loginInfo != null)
        //    {
        //        var account = loginInfo.Account;
        //        if (account != null && ((account.LoginType & LoginType.Remote) > 0))
        //        {
        //            return loginInfo;
        //        }
        //    }
        //    return null;
        //}

        /// <summary>
        /// 进行实际登录操作
        /// </summary>
        /// <param name="loginInfo"></param>
        /// <returns></returns>
        [Transaction(ReadOnly = false)]
        public string DoLogin(LoginInfo loginInfo)
        {
            if (loginInfo == null || loginInfo.Account == null)
            {
                return null;
            }

            FormsAuthenticationHelper.SignIn(loginInfo);

            var account = loginInfo.Account;
            string[] roles = account.Roles.Select(x=> x.Name).ToArray();
            //Roles.AddUserToRoles(account.FullName, roles);

            PrivilegeGroup group = this.GetDynamicPrivileges(account);
            string[] privileges = group.Privileges.Select(x=>x.Name).ToArray();
            Roles.AddUserToRoles(account.FullName, privileges);

            if (logger.IsInfoEnabled)
            {
                logger.Info(string.Format("用户 {0} 登录成功，分配权限：{1}",
                    account.FullName, account.Roles));
            }

            try
            {
                account.LastLoginTime = account.CurrentLoginTime;
                account.CurrentLoginTime = DateTime.Now;
                account.LoginCount++;
                this.AccountDao.Update(account);
            }
            catch (Exception ex)
            {
                if (logger.IsWarnEnabled)
                {
                    logger.Warn(string.Format("用户 {0} 的登录信息未能成功更新。", account.FullName), ex);
                }
            }

            return LoginInfoRegistry.Instance.Registry(loginInfo);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="clearInvalidTicket"></param>
        /// <returns></returns>
        [Transaction(ReadOnly=false)]
        public LoginInfo GetLoginInfo(bool clearInvalidTicket)
        {
            return LoginInfoRegistry.Instance.GetLoginInfo(true);
        }

        /// <summary>
        /// 注销
        /// </summary>
        [Transaction(ReadOnly=false)]
        public void Logout()
        {
            var loginInfo = LoginInfoRegistry.Instance.GetLoginInfo(true);
            LoginInfoRegistry.Instance.UnRegistry(loginInfo.Guid.ToString());
            if (loginInfo != null)
            {
                Account account = loginInfo.Account;
                string[] roleNames = Roles.GetRolesForUser(account.FullName);
                if (roleNames.Length > 0)
                {
                    Roles.RemoveUserFromRoles(account.FullName, roleNames);
                }
                if (logger.IsInfoEnabled)
                {
                    logger.Info(string.Format("用户 {0} 注销成功，删除权限：{1}",
                        account.FullName, string.Join(", ", roleNames)));
                }
            }

            FormsAuthenticationHelper.SignOut();
        }

        #endregion

//        /// <summary>
//        /// 同步域中的角色信息
//        /// </summary>
//        /// <param name="context"></param>
//        private void SyncDomainRoles(SyncDomainContext context)
//        {
//            logger.Debug("开始同步域中的角色信息 ...");

//            // 获取当前本地存储的角色和域中的安全组
//            IList<Role> roles = this.RoleDao.SelectAll();
//            IList<SecurityGroup> securityGroups = context.SelectAllSecurityGroups();

//            foreach (Role role in roles)
//            {
//                // 只处理本地存储中关联到域中的角色
//                if (role.Guid != null)
//                {
//                    // 查找相关的安全组
//                    SecurityGroup refGroup = null;
//                    foreach (SecurityGroup securityGroup in securityGroups)
//                    {
//                        if (securityGroup.Guid.Equals(role.Guid.Value))
//                        {
//                            refGroup = securityGroup;
//                            // 移除找到的相关组，保证 securityGroups 中的都不存在对应的本地角色
//                            securityGroups.Remove(securityGroup);
//                            break;
//                        }
//                    }

//                    if (refGroup != null)
//                    {
//                        // 找到，则更新信息
//                        if (refGroup.Name.StartsWith(groupNamePrefix))
//                        {
//                            role.Name = refGroup.Name.Substring(groupNamePrefixLength);
//                        }
//                        else
//                        {
//                            role.Name = refGroup.Name;
//                        }
//                        role.DisplayName = refGroup.Description ?? role.Name;
//                        if (string.IsNullOrEmpty(role.Description))
//                        {
//                            role.Description = refGroup.Description ?? string.Empty;
//                        }
//                        role.Detached = false;
//                        this.RoleDao.SaveOrUpdate(role);

//                        if (logger.IsDebugEnabled)
//                        {
//                            logger.Debug(string.Format("更新角色信息: {0} - {1}", role.Name, role.Guid));
//                        }
//                    }
//                    else if (!role.Detached)
//                    {
//                        // 未找到，则解除关联
//                        role.Detached = true;
//                        this.RoleDao.SaveOrUpdate(role);

//                        if (logger.IsDebugEnabled)
//                        {
//                            logger.Debug(string.Format("解除角色关联: {0} - {1}", role.Name, role.Guid));
//                        }
//                    }
//                }
//            }

//            // 将没有相关的安全组作为新的角色添加到本地
//            foreach (SecurityGroup securityGroup in securityGroups)
//            {
//                Role role = CreateRole(context, securityGroup);
//                if (role != null)
//                {
//                    roles.Add(role);
//                }
//            }

//            // 更新角色所属帐号
//            logger.Debug("更新角色所属帐号 ...");
//            foreach (Role role in roles)
//            {
//                if (role.Guid != null)
//                {
//                    Check.Assert(role.Accounts != null);

//                    while (role.Accounts.Count > 0)
//                    {
//                        role.RemoveAccount(role.Accounts.First());
//                    }
//                    this.RoleDao.SaveOrUpdate(role);
//                }
//            }
//            this.RoleDao.Flush();

//            foreach (Role role in roles)
//            {
//                if (role.Guid != null)
//                {
//                    IList<Staff> staffs = context.SelectMembers(role.Guid.Value, true);
//                    foreach (Staff staff in staffs)
//                    {
//                        Account account = this.AccountDao.FindByGuid(staff.Guid);
//                        if (account == null)
//                        {
//                            Group group = GetGroup(context, staff.Department);
//                            account = new Account()
//                            {
//                                Guid = staff.Guid,
//                                Name = staff.DisplayName,
//                                EnglishName = staff.EnglishName,
//                                EmployeeId = staff.EmployeeId,
//                                Group = group,
//                            };
//                            this.AccountDao.Save(account);
//                        }
//                        role.AddAccount(account);
//                    }
//                    this.RoleDao.SaveOrUpdate(role);
//                }
//            }
//            this.RoleDao.Flush();

//            logger.Debug("完成同步域中的角色信息 !!!");
//        }

//        /// <summary>
//        /// 更新域中的群组信息
//        /// </summary>
//        /// <param name="context"></param>
//        private void SyncDomainGroups(SyncDomainContext context)
//        {
//            logger.Debug("开始同步域中的群组信息 ...");

//            // 获取当前本地存储的群组集合和域中的部门信息
//            IList<Group> groups = this.GroupDao.SelectAll();
//            IList<Department> departments = context.SelectAllDepartments();

//            foreach (Group group in groups)
//            {
//                // 只处理本地存储中关联到域的群组
//                if (group.Guid != null)
//                {
//                    // 如果该群组已经处理过，则忽略
//                    if (context.GetGroup(group.Guid.Value) != null)
//                    {
//                        continue;
//                    }

//                    // 查找相关的部门
//                    Department refDepartment = null;
//                    foreach (Department department in departments)
//                    {
//                        if (department.Guid.Equals(group.Guid.Value))
//                        {
//                            refDepartment = department;
//                            // 移除找到的相关部门，保证 departments 中的都不存在对应的本地群组
//                            departments.Remove(department);
//                            break;
//                        }
//                    }

//                    if (refDepartment != null)
//                    {
//                        // 找到，则更新信息
//                        UpdateGroup(context, group, refDepartment);
//                    }
//                    else if (!group.Detached)
//                    {
//                        // 未找到，则解除关联
//                        group.Detached = true;
//                        this.GroupDao.SaveOrUpdate(group);

//                        if (logger.IsDebugEnabled)
//                        {
//                            logger.Debug(string.Format("解除群组关联: {0} - {1}", group.Name, group.Guid));
//                        }
//                    }

//                    context.CacheGroup(group);
//                }
//            }

//            // 将没有相关的部门作为新的群组添加到本地
//            foreach (Department department in departments)
//            {
//                Group group = GetGroup(context, department);
//                if (group != null)
//                {
//                    groups.Add(group);
//                }
//            }

//            logger.Debug("完成同步域中的群组信息 !!!");
//        }

//        /// <summary>
//        /// 更新域中的帐号信息
//        /// </summary>
//        /// <param name="context"></param>
//        private void SyncDomainAccounts(SyncDomainContext context)
//        {
//            logger.Debug("开始同步域中的帐号信息 ...");

//            // 获取当前本地存储的帐号集合和域中的职员信息
//            IList<Account> accounts = this.AccountDao.SelectAll();
//            IList<Staff> staffs = context.SelectAllStaff();

//            foreach (Account account in accounts)
//            {
//                // 查找相关的职员
//                Staff refStaff = null;
//                if (account.Guid != null)
//                {
//                    foreach (Staff staff in staffs)
//                    {
//                        if (account.Guid.Value.Equals(staff.Guid))
//                        {
//                            refStaff = staff;
//                            // 移除找到的相关职员，保证 staffs 中的都不存在对应的本地帐号
//                            staffs.Remove(refStaff);
//                            break;
//                        }
//                    }
//                }

//                // 只处理已启用帐号，已禁用的帐号将保持原状
//                if (!account.Disabled)
//                {
//                    if (refStaff != null)
//                    {
//                        // 找到，则更新信息
//                        UpdateAccount(context, account, refStaff);
//                    }
//                    else
//                    {
//                        // 未找到，则禁用帐号
//                        account.Disabled = true;
//                        this.AccountDao.SaveOrUpdate(account);

//                        if (logger.IsDebugEnabled)
//                        {
//                            logger.Debug(string.Format("禁用帐号: {0} - {1}", account.Name, account.Guid));
//                        }
//                    }
//                }
//            }

//            // 将没有相关的职员作为新的帐号添加到本地
//            foreach (Staff staff in staffs)
//            {
//                Account account = CreateAccount(context, staff);
//                if (account != null)
//                {
//                    accounts.Add(account);
//                }
//            }

//            logger.Debug("完成同步域中的帐号信息 !!!");
//        }

//        /// <summary>
//        /// 获取部门信息
//        /// </summary>
//        /// <param name="context"></param>
//        /// <param name="department"></param>
//        /// <returns></returns>
//        private Group GetGroup(SyncDomainContext context, Department department)
//        {
//            if (department == null)
//            {
//                return null;
//            }

//            Group group = context.GetGroup(department.Guid);
//            if (group != null)
//            {
//                return group;
//            }

//            group = this.GroupDao.FindByGuid(department.Guid);
//            if (group == null)
//            {
//                // 指定部门在本地不存在，则新创建该群组
//                group = new Group()
//                {
//                    Guid = department.Guid,
//                    Name = department.Name,
//                    DisplayName = department.Description ?? department.Name,
//                    Detached = false,
//                    Description = department.Description ?? string.Empty,
//                    ChildGroups = new List<Group>(),
//                    Members = new List<Account>(),
//                };

//                // 指定父部门
//                if (department.ParentGroupGuid != null)
//                {
//                    Department parentDepartment = context.FindDepartmentByGuid(department.ParentGroupGuid.Value);
//                    group.ParentGroup = GetGroup(context, parentDepartment);
//                }

//                // 指定管理员
//                Account securityManager = null;
//                Account manager = null;
//                if (department.ManagerGuid != null)
//                {
//                    manager = securityManager = GetAccount(context, department.ManagerGuid.Value);
//                }
//#if 使用父群组的管理员填充
//                else if (group.ParentGroup != null)
//                {
//                    securityManager = group.ParentGroup.SecurityManager;
//                    manager = group.ParentGroup.Manager;
//                }
//#endif
//                group.SecurityManager = securityManager;
//                group.SecurityManagerFromDomain = securityManager;
//                group.Manager = manager;
//                group.ManagerFromDomain = manager;

//                this.GroupDao.Save(group);

//                if (group.ParentGroup == null)
//                {
//                    group.Label = group.Id.ToString();
//                }
//                else
//                {
//                    group.Label = string.Concat(group.ParentGroup.Label, '.', group.Id);
//                }
//                this.GroupDao.Update(group);

//                if (logger.IsDebugEnabled)
//                {
//                    logger.Debug(string.Format("增加新群组: {0} - {1}", group.Name, group.Guid));
//                }
//            }
//            else
//            {
//                // 存在则更新群组信息
//                UpdateGroup(context, group, department);
//            }

//            context.CacheGroup(group);
//            return group;
//        }

//        /// <summary>
//        /// 更新群组
//        /// </summary>
//        /// <param name="context"></param>
//        /// <param name="group"></param>
//        /// <param name="department"></param>
//        private void UpdateGroup(SyncDomainContext context, Group group, Department department)
//        {
//            group.Name = department.Name;
//            group.DisplayName = department.Description ?? department.Name;
//            if (string.IsNullOrEmpty(group.Description))
//            {
//                group.Description = department.Description ?? string.Empty;
//            }
//            group.Detached = false;

//            // 指定父部门
//            if (department.ParentGroupGuid == null)
//            {
//                group.ParentGroup = null;
//                group.Label = group.Id.ToString();
//            }
//            else
//            {
//                Department parentDepartment = context.FindDepartmentByGuid(department.ParentGroupGuid.Value);
//                group.ParentGroup = GetGroup(context, parentDepartment);
//                group.Label = string.Concat(group.ParentGroup.Label, '.', group.Id);
//            }

//            // 指定管理员
//            if (department.ManagerGuid != null)
//            {
//                Account managerFromDomain = GetAccount(context, department.ManagerGuid.Value);

//                // 仅在未设置管理员，或者管理员为从域上自动获取时，才允许进行自动同步
//                if (group.SecurityManager == null || group.SecurityManager.Equals(group.SecurityManagerFromDomain))
//                {
//                    group.SecurityManager = managerFromDomain;
//                }
//                group.SecurityManagerFromDomain = managerFromDomain;

//                if (group.Manager == null || group.Manager.Equals(group.ManagerFromDomain))
//                {
//                    group.Manager = managerFromDomain;
//                }
//                group.ManagerFromDomain = managerFromDomain;
//            }
//            else
//            {
//                // 若本地设置的管理员和上一次同步的结果一致，则重新更新本地设置
//                if (group.SecurityManager == null || group.SecurityManager.Equals(group.SecurityManagerFromDomain))
//                {
//#if 使用父群组的管理员填充
//                    group.SecurityManager = group.ParentGroup == null ? null : group.ParentGroup.SecurityManager;
//#else
//                    group.SecurityManager = null;
//#endif
//                    group.SecurityManagerFromDomain = group.SecurityManager;
//                }
//                else
//                {
//                    group.SecurityManagerFromDomain = null;
//                }

//                if (group.Manager == null || group.Manager.Equals(group.ManagerFromDomain))
//                {
//#if 使用父群组的管理员填充
//                    group.Manager = group.ParentGroup == null ? null : group.ParentGroup.Manager;
//#else
//                    group.Manager = null;
//#endif
//                    group.ManagerFromDomain = group.Manager;
//                }
//                else
//                {
//                    group.ManagerFromDomain = null;
//                }
//            }

//            this.GroupDao.Update(group);

//            if (logger.IsDebugEnabled)
//            {
//                logger.Debug(string.Format("更新群组信息: {0} - {1}", group.Name, group.Guid));
//            }
//        }

//        /// <summary>
//        /// 创建角色
//        /// </summary>
//        /// <param name="context"></param>
//        /// <param name="securityGroup"></param>
//        /// <returns></returns>
//        private Role CreateRole(SyncDomainContext context, SecurityGroup securityGroup)
//        {
//            string roleName = securityGroup.Name.StartsWith(groupNamePrefix) ? securityGroup.Name.Substring(groupNamePrefixLength) : securityGroup.Name;

//            Role role = new Role()
//            {
//                Guid = securityGroup.Guid,
//                Name = roleName,
//                DisplayName = securityGroup.Description ?? roleName,
//                Description = securityGroup.Description ?? string.Empty,
//                Detached = false,
//                PrivilegeAssignable = true,
//                Accounts = new List<Account>(),
//            };

//            this.RoleDao.Save(role);

//            if (logger.IsDebugEnabled)
//            {
//                logger.Debug(string.Format("增加新角色: {0} - {1}", roleName, role.Guid));
//            }

//            return role;
//        }

//        /// <summary>
//        /// 获取职员信息
//        /// </summary>
//        /// <param name="context"></param>
//        /// <param name="accountGuid"></param>
//        /// <returns></returns>
//        private Account GetAccount(SyncDomainContext context, Guid accountGuid)
//        {
//            return this.AccountDao.FindByGuid(accountGuid);
//        }

//        /// <summary>
//        /// 创建帐号
//        /// </summary>
//        /// <param name="context"></param>
//        /// <param name="staff"></param>
//        /// <returns></returns>
//        private Account CreateAccount(SyncDomainContext context, Staff staff)
//        {
//            Group group = GetGroup(context, staff.Department);

//            Account account = new Account()
//            {
//                Guid = staff.Guid,
//                Name = staff.DisplayName,
//                EnglishName = staff.EnglishName,
//                EmployeeId = staff.EmployeeId,
//                Group = group,
//                GroupFromDomain = group,
//                Roles = new List<Role>(),
//                Disabled = staff.Invalid,
//            };

//            UserProfile profile = new UserProfile()
//            {
//                Account = account,
//                Email = staff.Email,
//                IsDefaultEmail = true,
//            };

//            this.AccountDao.Save(account);
//            this.UserProfileDao.Save(profile);

//            if (logger.IsDebugEnabled)
//            {
//                if (account.Disabled)
//                {
//                    logger.Debug(string.Format("增加新无效帐号: {0} - {1}", account.Name, account.Guid));
//                }
//                else
//                {
//                    logger.Debug(string.Format("增加新帐号: {0} - {1}", account.Name, account.Guid));
//                }
//            }

//            return account;
//        }

//        /// <summary>
//        /// 更新帐号信息
//        /// </summary>
//        /// <param name="context"></param>
//        /// <param name="account"></param>
//        /// <param name="staff"></param>
//        private void UpdateAccount(SyncDomainContext context, Account account, Staff staff)
//        {
//            account.Name = staff.DisplayName;
//            account.EnglishName = staff.EnglishName;
//            account.EmployeeId = staff.EmployeeId;

//            // 获取域上指定的群组
//            Group groupFromDomain = GetGroup(context, staff.Department);
//            // 只有当域上指定的群组发生改变后，才重新修正帐号的群组
//            if ((groupFromDomain == null) || (!groupFromDomain.Equals(account.GroupFromDomain)))
//            {
//                account.GroupFromDomain = groupFromDomain;
//                account.Group = groupFromDomain;
//            }

//            UserProfile profile = this.UserProfileDao.FindById(account.Id);
//            if (profile == null)
//            {
//                profile = new UserProfile()
//                {
//                    Account = account,
//                    Email = staff.Email,
//                    IsDefaultEmail = true,
//                };
//            }
//            else if (profile.IsDefaultEmail)
//            {
//                profile.Email = staff.Email;
//            }

//            // 已禁用帐号
//            if (staff.Invalid)
//            {
//                account.Disabled = true;
//            }

//            this.AccountDao.SaveOrUpdate(account);
//            this.UserProfileDao.SaveOrUpdate(profile);

//            if (logger.IsDebugEnabled)
//            {
//                if (account.Disabled)
//                {
//                    logger.Debug(string.Format("禁用帐号: {0} - {1}", account.Name, account.Guid));
//                }
//                else
//                {
//                    logger.Debug(string.Format("更新帐号信息: {0} - {1}", account.Name, account.Guid));
//                }
//            }
//        }
    }
}
